home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-05 / drivers3.zip / DE600.ASM < prev    next >
Assembly Source File  |  1992-03-05  |  45KB  |  2,153 lines

  1. PAGE  ,132
  2.    .286c
  3. version equ     0
  4.  
  5.     include defs.asm        ;SEE ENCLOSED COPYRIGHT MESSAGE
  6.  
  7. ;/* PC/FTP Packet Driver source, conforming to version 1.09 of the spec
  8. ;*  Portions (C) Copyright 1990 D-Link, Inc.
  9. ;*
  10. ;*  Permission is granted to any individual or institution to use, copy,
  11. ;*  modify, or redistribute this software and its documentation provided
  12. ;*  this notice and the copyright notices are retained.  This software may
  13. ;*  not be distributed for profit, either in original form or in derivative
  14. ;*  works.  D-Link, inc. makes no representations about the suitability
  15. ;*  of this software for any purpose.  D-LINK GIVES NO WARRANTY,
  16. ;*  EITHER EXPRESS OR IMPLIED, FOR THE PROGRAM AND/OR DOCUMENTATION
  17. ;*  PROVIDED, INCLUDING, WITHOUT LIMITATION, WARRANTY OF MERCHANTABILITY
  18. ;*  AND WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE.
  19. ;*/
  20.  
  21. BIT0            EQU     01H
  22. BIT1            EQU     02H
  23. BIT2            EQU     04H
  24. BIT3            EQU     08H
  25. BIT4            EQU     10H
  26. BIT5            EQU     20H
  27. BIT6            EQU     40H
  28. BIT7            EQU     80H
  29.  
  30. code    segment byte public
  31.     assume  cs:code, ds:code
  32.  
  33. ; DE-600's I/O port Table
  34. DAT             equ     0
  35. STAT            equ     1
  36. CMD             equ     2
  37.  
  38. ; DE-600's DATA port Command
  39. WRITE           equ     0004h   ;write memory
  40. READ            equ     0104h   ;read  memory
  41. STATUS          equ     0204h   ;read  status register
  42. COMMAND         equ     0304h   ;write command register
  43. NUL_CMD         equ     0ch     ;null command
  44. RX_LEN          equ     0504h   ;read  Rx packet length
  45. TX_ADR          equ     0604h   ;write Tx address
  46. RW_ADR          equ     0704h   ;write memory address
  47.  
  48. ;< COMMAND   bits 7-0 >
  49. RXEN            equ     08h    ; bit 3
  50. TXEN            equ     04h    ; bit 2
  51. LOOPBACK        equ     0Ch    ; RXEN=1, TXEN=1
  52. RX_NONE         equ     00h    ; M1=0, M0=0 (bit 1,0)
  53. RX_ALL          equ     01h    ; M1=0, M0=1
  54. RX_BP           equ     02h    ; M1=1, M0=0
  55. RX_MBP          equ     03h    ; M1=1, M0=1
  56. RESET           equ     80h    ; set bit 7 high
  57. STOP_RESET      equ     00h    ; set bit 7 low
  58. ;  bit 6   -- IRQ inverse
  59. ;  bit 5,4 -- Rx Page Number  ( RA12=1, RA11=0 or 1 )
  60.  
  61. ;< TX_ADR   bit 7, bit 4 >
  62. ;  bit 7   -- Tx Page Number  ( TA11=0 or 1 )
  63. ;  bit 4   -- Tx Page Number  ( TA12=0 )
  64. PAGE0           equ     00h
  65. PAGE1           equ     08h
  66. PAGE2           equ     10h
  67. PAGE3           equ     18h
  68.  
  69. ;< RW_ADR   bit 7, bit 5,4 >
  70. ;  bit 7   -- RW Page Number  ( H11 =? )
  71. ;  bit 4   -- RW Page Number  ( H12 =? )
  72. ;  bit 5   -- Address Maping  ( HA13=0 => Memory, HA13=1 => Node Number )
  73. HA13            equ     020h
  74.  
  75. ; DE-600's CMD port Command
  76. SLT_NIC         equ     004h  ;select Network Interface Card
  77. SLT_PRN         equ     01Ch  ;select Printer
  78. NML_PRN         equ     0ECh  ;normal Printer situation
  79. IRQEN           equ     010h  ;enable IRQ line
  80.  
  81. ; DE-600's STAT port bits 7-4
  82. RXBUSY          equ     80h
  83. GOOD            equ     40h
  84. RESET_FLAG      equ     20h
  85. T16             equ     10h
  86. TXBUSY          equ     08h
  87.  
  88. BFRSIZ          equ     2048    ;number of bytes in a buffer
  89. PRNTABADD       equ     408h    ;DOS printer table address
  90. RX_MIN_LEN      equ     18      ;= EADDR_LEN + EADDR_LEN + TYPE_LEN + CRC
  91.  
  92. write_sub_delay    macro    reg
  93.     mov     al,reg            ;output the low nibble.
  94.     shl     al,cl            ;cl must be four.
  95.     or      al,ch
  96.     xor     al,08h            ;raise the write line.
  97.     out     dx,al
  98.     call    delay
  99.  
  100.     xor     al,08h            ;lower the write line
  101.     out     dx,al
  102.     call    delay
  103.  
  104.     mov     al,reg            ;output the high nibble.
  105.     and     al,not 0fh        ;get us some zero bits.
  106.     or      al,ch
  107.     out     dx,al            ;(write line is low).
  108.     call    delay
  109.  
  110.     xor     al,08h            ;raise the write line.
  111.     out     dx,al
  112.     endm
  113.  
  114. write_sub_fast    macro    reg
  115.     mov     al,reg            ;output the low nibble.
  116.     shl     al,cl            ;cl must be four.
  117.     or      al,ch
  118.     out     dx,al
  119.  
  120.     mov     al,reg            ;output the high nibble.
  121.     and     al,not 0fh        ;get us some zero bits.
  122.     or      al,ch
  123.     xor     al,08h            ;raise the write line.
  124.     out     dx,al            ;(write line is low).
  125.     endm
  126.  
  127. write_sub_slow    macro    reg
  128.     mov     al,reg            ;output the low nibble.
  129.     shl     al,cl            ;cl must be four.
  130.     or      al,ch
  131.     out     dx,al
  132.     call    delay
  133.  
  134.     mov     al,reg            ;output the high nibble.
  135.     and     al,not 0fh        ;get us some zero bits.
  136.     or      al,ch
  137.     xor     al,08h            ;raise the write line.
  138.     out     dx,al            ;(write line is low).
  139.     endm
  140.  
  141. read_sub_fast    macro    reg
  142.     setport DAT
  143.     mov     al,ch
  144.     out     dx,al
  145.     pause
  146.  
  147.     setport STAT
  148.     in      al,dx
  149.     mov     reg,al
  150.     setport DAT
  151.     mov     al,ch
  152.     xor     al,08h
  153.     out     dx,al
  154.     pause
  155.  
  156.     setport STAT
  157.     in      al,dx
  158.     shr     reg,cl
  159.     and     al,0f0h
  160.     or      reg,al
  161.     endm
  162.  
  163.  
  164. read_sub_slow    macro    reg
  165.     setport DAT
  166.     mov     al,ch
  167.     out     dx,al
  168.     call    delay
  169.  
  170.     setport STAT
  171.     in      al,dx
  172.     mov     reg,al
  173.     setport DAT
  174.     mov     al,ch
  175.     xor     al,08h
  176.     out     dx,al
  177.     call    delay
  178.  
  179.     setport STAT
  180.     in      al,dx
  181.     shr     reg,cl
  182.     and     al,0f0h
  183.     or      reg,al
  184.     endm
  185.  
  186.  
  187. read_sub_delay    macro    reg, first
  188.     setport DAT
  189.     mov     al,ch
  190.   if first
  191.     xor     al,08h
  192.   endif
  193.     out     dx,al
  194.     call    delay
  195.  
  196.   if first
  197.     xor     al,08h
  198.     out     dx,al
  199.     call    delay
  200.   endif
  201.  
  202.     setport STAT
  203.     in      al,dx
  204.     mov     reg,al
  205.     setport DAT
  206.     mov     al,ch
  207.     xor     al,08h
  208.     out     dx,al
  209.     call    delay
  210.  
  211.     setport STAT
  212.     in      al,dx
  213.     shr     reg,cl
  214.     and     al,0f0h
  215.     or      reg,al
  216.     endm
  217.  
  218.  
  219. pause    macro
  220.     jmp    $+2
  221.     endm
  222.  
  223.     public  int_no
  224. int_no          db      7,0,0,0         ; IRQ interrupt number
  225. io_addr         dw      03bch,0         ; I/O address for card (jumpers)
  226.  
  227.     public    driver_class, driver_type, driver_name, driver_function, parameter_list
  228. driver_class    db      BLUEBOOK, IEEE8023, 0 ;from the packet spec
  229. driver_type     db      31              ;from the packet spec
  230. driver_name     db      'DE600',0      ;name of the driver
  231. driver_function    db    2
  232. parameter_list    label    byte
  233.     db    1    ;major rev of packet driver
  234.     db    9    ;minor rev of packet driver
  235.     db    14    ;length of parameter list
  236.     db    EADDR_LEN    ;length of MAC-layer address
  237.     dw    GIANT    ;MTU, including MAC headers
  238.     dw    MAX_MULTICAST * EADDR_LEN    ;buffer size of multicast addrs
  239.     dw    0    ;(# of back-to-back MTU rcvs) - 1
  240.     dw    0    ;(# of successive xmits) - 1
  241. int_num    dw    0    ;Interrupt # to hook for post-EOI
  242.             ;processing, 0 == none,
  243.  
  244.     public    rcv_modes
  245. rcv_modes    dw    7        ;number of receive modes in our table.
  246.         dw    0               ;There is no mode zero
  247.         dw    rcv_mode_1
  248.         dw    0
  249.         dw    rcv_mode_3
  250.         dw    0
  251.         dw    rcv_mode_5
  252.         dw    rcv_mode_6
  253.  
  254. CurTxPage       db      08h             ;the BL value when OUT DATA,TX_ADR
  255. CurRxPage       db      20h             ;the BL value when OUT DATA,COMMAND
  256. TxStartAdd      dw      ?
  257. RxStartAdd      dw      ?
  258. InitRxTxReg     dw      ?
  259. RxPktLen        dw      ?
  260. TxPktLen        dw      ?
  261. Mode_RxPg       db      ?
  262. Mode            db      RX_BP
  263. IRQinverse      db      0               ; = 40h for XT printer adapter
  264. NICstatus       db      0
  265. In_ISR          db      0
  266. In_Tx           db      0
  267. printer         dw      408h
  268. PS2             db      0
  269.  
  270. our_type        dw      ?,?
  271. our_address     db      EADDR_LEN + EADDR_LEN dup(0) ;temporarily hold our address
  272.  
  273.  
  274.     public    as_send_pkt
  275. ; The Asynchronous Transmit Packet routine.
  276. ; Enter with es:di -> i/o control block, ds:si -> packet, cx = packet length,
  277. ;   interrupts possibly enabled.
  278. ; Exit with nc if ok, or else cy if error, dh set to error number.
  279. ;   es:di and interrupt enable flag preserved on exit.
  280. as_send_pkt:
  281.     ret
  282.  
  283.     public    drop_pkt
  284. ; Drop a packet from the queue.
  285. ; Enter with es:di -> iocb.
  286. drop_pkt:
  287.     assume    ds:nothing
  288.     ret
  289.  
  290.     public    xmit
  291. ; Process a transmit interrupt with the least possible latency to achieve
  292. ;   back-to-back packet transmissions.
  293. ; May only use ax and dx.
  294. xmit:
  295.     assume    ds:nothing
  296.     ret
  297.  
  298.  
  299.     public  send_pkt
  300. send_pkt:
  301. ;enter with ds:si -> packet, cx = packet length.
  302. ;exit with nc if ok, or else cy if error, dh set to error number.
  303.     assume  ds:nothing
  304. ;select DE-600
  305.     mov     al,SLT_NIC
  306. ;*** CMD sub ***
  307.     loadport
  308.     setport CMD
  309.     out     dx,al
  310. ;*** End CMD sub ***
  311.     mov     In_Tx,1
  312.     call    delay
  313.  
  314.     cmp     cx,RUNT         ; minimum length for Ether
  315.     jae     LengthOK
  316.     mov     cx,RUNT         ; make sure size at least RUNT
  317. LengthOK:
  318.     inc     cx
  319.     and     cx,not 1
  320.  
  321.     mov     di,cx
  322. ;change Tx page to another free buffer
  323.     xor     CurTxPage,08h
  324.  
  325.     mov     bx,offset send_pkt_pointer
  326.     jmp     cs:[bx]
  327.  
  328. send_pkt_pointer        dw      offset send_pkt0
  329.  
  330. send_pkt0:
  331. ;set Tx Pointer for moving packet
  332.     mov     ax,BFRSIZ
  333.     sub     ax,cx           ;AX = the pointer to TX
  334.     or      ah,CurTxPage
  335.     mov     TxStartAdd,ax   ;save Current Tx Packet Start Address
  336.     mov     bx,ax           ;write memory address
  337.     mov     cx,RW_ADR
  338.     setport DAT
  339.     write_sub_fast    bl
  340.     write_sub_fast    bh
  341.     cld
  342.     mov     cx,WRITE        ;write packet into memory
  343.     mov     ah,ch
  344.     xor     ah,08h
  345. write_mem:
  346.     lodsb
  347.     mov     bl,al
  348.     shl     al,cl
  349.     or      al,ch
  350.     out     dx,al
  351.  
  352.     mov     al,bl
  353.     and     al,0f0h
  354.     or      al,ah
  355.     dec     di
  356.     out     dx,al
  357.     jnz     write_mem
  358.  
  359.     mov     cx,4000h
  360.     setport STAT
  361. wait_Tx_idle:
  362.     in      al,dx
  363.     test    al,TXBUSY       ; Is the previous Tx successful ?
  364.     jz      command_to_Tx   ; Yes, TXBUSY is low. Then could Tx next packet.
  365.     loop    wait_Tx_idle
  366.  
  367. command_to_Tx:
  368. ;set Tx Pointer at beginning of packet
  369.     mov     bx,TxStartAdd
  370.     mov     cx,TX_ADR
  371.     loadport
  372.     setport DAT
  373.     write_sub_fast    bl
  374.     write_sub_fast    bh
  375.  
  376. ;Enable interrupt and start Tx
  377.     mov     bl,Mode_RxPg
  378.     mov     cx,COMMAND
  379.     write_sub_fast    bl
  380.     or      bl,TXEN
  381.     write_sub_fast    bl
  382.  
  383. Exit_Send_Packet:
  384.     mov     In_Tx,0
  385.  
  386.     cmp     In_ISR,0
  387.     jne     using_NIC_now
  388.     mov     al,SLT_PRN
  389.     loadport
  390.     setport CMD
  391.     out     dx,al
  392.  
  393.     cmp     PS2,0
  394.     jnz     using_NIC_now
  395.     setport STAT
  396.     in      al,dx
  397.     and     al,40h
  398.     xor     al,IRQinverse
  399.     jz      using_NIC_now
  400.     call    trigger_int
  401. using_NIC_now:
  402.     clc
  403.     ret
  404.  
  405.  
  406. send_pkt1:
  407. ;set Tx Pointer for moving packet
  408.     mov     ax,BFRSIZ
  409.     sub     ax,cx           ;AX = the pointer to TX
  410.     or      ah,CurTxPage
  411.     mov     TxStartAdd,ax   ;save Current Tx Packet Start Address
  412.     mov     bx,ax           ;write memory address
  413.     mov     cx,RW_ADR
  414.     loadport
  415.     setport DAT
  416.     write_sub_slow    bl
  417.     call    delay
  418.     write_sub_slow    bh
  419.  
  420.     cld
  421.     mov     cx,WRITE        ;write packet into memory
  422.     mov     ah,ch
  423.     xor     ah,08h
  424. write_mem1:
  425.     lodsb
  426.     mov     bl,al
  427.     shl     al,cl
  428.     or      al,ch
  429.     out     dx,al
  430.     call    delay
  431.  
  432.     mov     al,bl
  433.     and     al,0f0h
  434.     or      al,ah
  435.     dec     di
  436.     out     dx,al
  437.     call    delay
  438.     jnz     write_mem1
  439.  
  440.     mov     cx,4000h
  441.     setport STAT
  442. wait_Tx_idle1:
  443.     in      al,dx
  444.     test    al,TXBUSY       ; Is the previous Tx successful ?
  445.     jz      command_to_Tx1  ; Yes, TXBUSY is low. Then could Tx next packet.
  446.     loop    wait_Tx_idle1
  447.  
  448. command_to_Tx1:
  449. ;set Tx Pointer at beginning of packet
  450.     mov     bx,TxStartAdd
  451.     mov     cx,TX_ADR
  452.     loadport
  453.     setport DAT
  454.     write_sub_slow    bl
  455.     call    delay
  456.     write_sub_slow    bh
  457.     call    delay
  458.  
  459. ;Enable interrupt and start Tx
  460.     mov     bl,Mode_RxPg
  461.     mov     cx,COMMAND
  462.     write_sub_slow    bl
  463.     call    delay
  464.     or      bl,TXEN
  465.     write_sub_slow    bl
  466.     jmp     Exit_Send_Packet
  467.  
  468.  
  469. send_pkt2:
  470. ;set Tx Pointer for moving packet
  471.     mov     ax,BFRSIZ
  472.     sub     ax,cx           ;AX = the pointer to TX
  473.     or      ah,CurTxPage
  474.     mov     TxStartAdd,ax   ;save Current Tx Packet Start Address
  475.     mov     bx,ax           ;write memory address
  476.     mov     cx,RW_ADR
  477.     loadport
  478.     setport DAT
  479.     write_sub_delay    bl
  480.     call    delay
  481.     write_sub_delay    bh
  482.     cld
  483.     mov     cx,WRITE        ;write packet into memory
  484. write_mem2:
  485.     lodsb
  486.     mov     bl,al            ;except for this line,
  487.     shl     al,cl            ;  it's write_sub_delay
  488.     or      al,ch
  489.     xor     al,08h
  490.     out     dx,al
  491.     call    delay
  492.  
  493.     xor     al,08h
  494.     out     dx,al
  495.     call    delay
  496.  
  497.     mov     al,bl
  498.     and     al,0f0h
  499.     or      al,ch
  500.     out     dx,al
  501.     call    delay
  502.  
  503.     xor     al,08h
  504.     out     dx,al
  505.     call    delay
  506.     dec     di
  507.     jnz     write_mem2
  508.  
  509.     mov     cx,4000h
  510.     setport STAT
  511. wait_Tx_idle2:
  512.     in      al,dx
  513.     test    al,TXBUSY       ; Is the previous Tx successful ?
  514.     jz      command_to_Tx2  ; Yes, TXBUSY is low. Then could Tx next packet.
  515.     loop    wait_Tx_idle2
  516.  
  517. command_to_Tx2:
  518. ;set Tx Pointer at beginning of packet
  519.     mov     bx,TxStartAdd
  520.     mov     cx,TX_ADR
  521.     loadport
  522.     setport DAT
  523.     write_sub_delay    bl
  524.     call    delay
  525.     write_sub_delay    bh
  526.     call    delay
  527.  
  528. ;Enable interrupt and start Tx
  529.     mov     bl,Mode_RxPg
  530.     mov     cx,COMMAND
  531.     write_sub_delay    bl
  532.     call    delay
  533.     or      bl,TXEN
  534.     write_sub_delay    bl
  535.     jmp     Exit_Send_Packet
  536.  
  537.  
  538. trigger_int:
  539.     mov     al,SLT_NIC
  540.     call    CMD_sub
  541.  
  542.     mov     bl,Mode_RxPg
  543.     xor     bl,BIT6
  544.     mov     cx,COMMAND
  545.     call    Write_sub
  546.  
  547.     mov     al,SLT_PRN
  548.     call    CMD_sub
  549.  
  550.     call    delay
  551.     call    delay
  552.  
  553.     mov     al,SLT_NIC
  554.     call    CMD_sub
  555.  
  556.     mov     bl,Mode_RxPg
  557.     mov     cx,COMMAND
  558.     call    Write_sub
  559.     ret
  560.  
  561.  
  562.     public  get_address
  563. get_address:
  564. ;get the address of the interface.
  565. ;enter with es:di -> place to get the address, cx = size of address buffer.
  566.     assume  ds:code
  567.     cmp     cx,EADDR_LEN            ;make sure that we have enough room.
  568.     jb      cant_get_address
  569.  
  570. ;select DE-600
  571.     cld
  572.     mov     si,offset our_address
  573.     rep     movsb
  574.     mov     cx,EADDR_LEN
  575.     clc
  576.     ret
  577. cant_get_address:
  578.     stc
  579.     ret
  580.  
  581.  
  582. rcv_mode_1:
  583.     mov     cl,RX_NONE
  584.     jmp     short set_RXCR
  585. rcv_mode_3:
  586.     mov     cl,RX_BP
  587.     jmp     short set_RxCR
  588. rcv_mode_5:
  589.     mov     cl,RX_MBP
  590.     jmp     short set_RxCR
  591. rcv_mode_6:
  592.     mov     cl,RX_ALL
  593. set_RxCR:
  594.     mov     Mode,cl
  595.     mov     bl,cl
  596.     or      bl,CurRxPage            ; Add original Rx Page
  597.     mov     Mode_RxPg,bl            ; Save Rx Mode & Rx Page
  598. ;select DE-600
  599.     loadport
  600.     setport CMD
  601.     in      al,dx
  602.     pause
  603.     test    al,BIT4
  604.     jz      in_IC_mode
  605. ;not active, we have to put a wrapper around it.
  606.     mov     al,int_no
  607.     call    maskint
  608.  
  609.     mov     al,SLT_NIC        ;turn on the NIC.
  610.     call    CMD_sub
  611.     call    in_IC_mode        ;now we're in the right mode.
  612.     mov     al,SLT_PRN        ;turn on the PRN.
  613.     call    CMD_sub
  614.  
  615.     mov     al,int_no
  616.     call    unmaskint
  617.     ret
  618.  
  619. in_IC_mode:
  620.     mov     cx,COMMAND              ; Set new Rx Mode
  621.     call    Write_sub
  622.     ret
  623.  
  624.  
  625.     extrn   maskint : near
  626.     extrn   unmaskint : near
  627.  
  628.     public  set_address
  629. set_address:
  630. ;Set Ethernet address on controller
  631. ;enter with ds:si -> Ethernet address, CX = length of address.
  632. ;exit with nc if okay, or cy, dh=error if any errors.
  633. ;
  634.     assume  ds:nothing
  635.     cmp     cx,EADDR_LEN            ;make sure that we have enough room.
  636.     je      can_set_address
  637.     mov     dh,BAD_ADDRESS
  638.     stc
  639.     jmp     set_address_none
  640.  
  641. ;select DE-600
  642. can_set_address:
  643.     loadport
  644.     setport CMD
  645.     in      al,dx
  646.     push    ax
  647.     test    al,BIT4
  648.     jz      IC_mode
  649.  
  650.     mov     al,int_no
  651.     call    maskint
  652.     mov     al,SLT_NIC
  653.     call    CMD_sub
  654. IC_mode:
  655.     mov     cx,RW_ADR
  656.     xor     bl,bl
  657.     call    Write_sub
  658.     or      bl,HA13
  659.     call    Write_sub
  660.  
  661.     cld
  662.     mov     bp,cs
  663.     mov     es,bp
  664.     mov     bp,si
  665.  
  666.     mov     cx,EADDR_LEN
  667.     mov     di,offset our_address
  668.     rep     movsb
  669.  
  670.     mov     si,bp
  671.     mov     di,EADDR_LEN
  672.     mov     cx,WRITE
  673. set_our_address:
  674.     lodsb
  675.     mov     bl,al
  676.     call    Write_sub
  677.     dec     di
  678.     jnz     set_our_address
  679.  
  680.     pop     ax
  681.     test    al,BIT4
  682.     jz      IC_mode1
  683.  
  684.     mov     al,SLT_PRN
  685.     call    CMD_sub
  686.     mov     al,int_no
  687.     call    unmaskint
  688. IC_mode1:
  689.     clc
  690. set_address_none:
  691.     push    cs
  692.     pop     ds
  693.     assume  ds:code
  694.     ret
  695.  
  696.  
  697.     public    set_multicast_list
  698. set_multicast_list:
  699. ;enter with ds:si ->list of multicast addresses, cx = number of addresses.
  700. ;return nc if we set all of them, or cy,dh=error if we didn't.
  701.     mov    dh,NO_MULTICAST
  702.     stc
  703.     ret
  704.  
  705.  
  706.     public    terminate
  707. terminate:
  708.     ret
  709.  
  710.  
  711.     public  reset_interface
  712. reset_interface:
  713.     mov     al,int_no
  714.     call    maskint
  715. ;select DE-600
  716.  
  717.     mov     al,SLT_NIC
  718.     call    CMD_sub
  719.  
  720. ; Pulse IE_RESET
  721.     mov     bl,RESET
  722.     mov     cx,COMMAND
  723.     call    Write_sub
  724.     mov     bl,STOP_RESET
  725.     call    Write_sub
  726.  
  727. ; Initialize Rx buffer pointer, and start receive
  728.     mov     bl,Mode_RxPg
  729.     mov     cx,COMMAND
  730.     call    Write_sub
  731.     or      bl,RXEN
  732.     call    Write_sub
  733.  
  734. ; Enable Printer Adapter IRQ line
  735.     mov     al,SLT_PRN
  736.     call    CMD_sub
  737.  
  738.     mov     al,int_no
  739.     call    unmaskint
  740.     ret
  741.  
  742.  
  743.     assume  ds:nothing
  744. Write_sub:
  745.     loadport
  746.     setport DAT
  747.     write_sub_delay    bl
  748.     ret
  749.  
  750. Read_sub:
  751.     loadport
  752.     setport DAT
  753.     mov     al,ch
  754.     xor     al,08h
  755.     out     dx,al
  756.     call    delay
  757.  
  758.     xor     al,08h
  759.     out     dx,al
  760.     call    delay
  761.  
  762.     setport STAT
  763.     in      al,dx
  764.     mov     bl,al
  765.     test    ch,BIT1
  766.     jz      not_READ_STATUS
  767.     dec     dx
  768.     mov     al,NUL_CMD
  769.     xor     al,08h
  770.     out     dx,al
  771.     call    delay
  772.  
  773.     xor     al,08h
  774.     out     dx,al
  775.     jmp     short End_read
  776. not_READ_STATUS:
  777.     setport DAT
  778.     mov     al,ch
  779.     xor     al,08h
  780.     out     dx,al
  781.     call    delay
  782.  
  783.     setport STAT
  784.     in      al,dx
  785.     shr     bl,cl
  786.     and     al,0f0h
  787.     or      bl,al
  788. End_read:
  789.     ret
  790.  
  791. CMD_sub:
  792.     loadport
  793.     setport CMD
  794.     out     dx,al
  795.     ret
  796.  
  797. delay:
  798.     nop     ; pointer 0
  799.     nop     ;         1
  800.     nop     ;         2
  801.     nop     ;         3
  802.     nop     ;         4
  803.     nop     ;         5
  804.     nop     ;         6
  805.     nop     ;         7
  806.     nop     ;         8
  807.     nop     ;         9
  808.     ret
  809.  
  810. ;called when we want to determine what to do with a received packet.
  811. ;enter with cx = packet length, es:di -> packet type, dl = packet class.
  812.     extrn   recv_find: near
  813.  
  814. ;called after we have copied the packet into the buffer.
  815. ;enter with ds:si ->the packet, cx = length of the packet.
  816.     extrn   recv_copy: near
  817.  
  818.     extrn   count_in_err: near
  819.     extrn   count_out_err: near
  820.  
  821. recv_pointer    dw      offset recv0
  822.  
  823.     public  recv
  824. recv:
  825. ;called from the recv isr.  All registers have been saved, and ds=cs.
  826. ;Upon exit, the interrupt will be acknowledged.
  827.     assume  ds:code
  828. ;select DE-600
  829.     mov     al,SLT_NIC
  830. ;*** CMD sub ***
  831.     loadport
  832.     setport CMD
  833.     out     dx,al
  834. ;*** End CMD sub ***
  835. ;set watch dog
  836.     mov     In_ISR,1
  837.     call    delay
  838.  
  839. ;Check the interrupt source, Rx or Tx ?
  840.     mov     cx,STATUS               ; Read NIC Status Register
  841. ;*** Read sub ***
  842.     setport DAT
  843.     mov     al,ch
  844.     out     dx,al
  845.     pause
  846.     setport STAT
  847.     in      al,dx
  848. ;*** End Read sub ***
  849.  
  850.     jmp    recv_pointer
  851.  
  852. recv0:
  853.     mov     NICstatus,al            ; save NIC status
  854.     setport DAT
  855.     test    al,GOOD                 ; Is Rx generating interrupt ?
  856.     mov     al,NUL_CMD
  857.     out     dx,al
  858.     jnz     Rx_Good_Pkt             ; Yes, take care of this situation.
  859.     mov     al,NICstatus
  860.     test    al,RXBUSY
  861.     jz      Enable_Rx
  862.     jmp     CheckTx
  863.  
  864. Enable_Rx:
  865. ;change Rx page & enable NIC to Rx
  866.     mov     bl,Mode_RxPg
  867.     mov     cx,COMMAND
  868.     setport DAT
  869.     write_sub_fast    bl
  870.     or      bl,RXEN
  871.     write_sub_fast    bl
  872.     jmp     CheckTx
  873.  
  874. Rx_Good_Pkt:
  875. ;Put it on the receive queue
  876.     mov     cx,RX_LEN               ; read Rx Packet Length
  877.     loadport
  878.     read_sub_fast    bl
  879.     read_sub_fast    bh
  880.  
  881.     sub     bx,4                    ;subtrate 4 CRC Byte Count
  882.     mov     RxPktLen,bx             ;save Rx Packet Length
  883.  
  884. ;change Rx page & enable NIC to Rx
  885.     xor     Mode_RxPg,10h
  886.     mov     bl,Mode_RxPg
  887.     mov     cx,COMMAND
  888.     setport DAT
  889.     write_sub_fast    bl
  890.     or      bl,RXEN
  891.     write_sub_fast    bl
  892.     xor     bx,bx
  893.     mov     bh,CurRxPage            ;BL = Current Rx Page
  894.     xor     CurRxPage,10h           ;change to next page for Rx
  895.     shr     bx,1                    ;shift BX to real memory address
  896.     mov     RxStartAdd,bx           ;save just Rx Packet Start Address
  897.  
  898.     add     bx,EADDR_LEN+EADDR_LEN  ;seek to the TYPE word
  899.     mov     cx,RW_ADR
  900.     write_sub_fast    bl
  901.     write_sub_fast    bh
  902.     pause
  903.     mov     cx,READ            ;read the TYPE word
  904.     read_sub_fast    bl
  905.     read_sub_fast    bh
  906.  
  907.     mov     our_type,bx        ;save the TYPE word
  908.  
  909.     mov     cx,READ            ;read the TYPE word
  910.     read_sub_fast    bl
  911.     read_sub_fast    bh
  912.  
  913.     mov     our_type[2],bx        ;save the TYPE word
  914.  
  915.     mov     ax,ds
  916.     mov     es,ax
  917.     mov     di,offset our_type
  918.     mov     cx,RxPktLen
  919.  
  920.     mov    dl, BLUEBOOK        ;assume bluebook Ethernet.
  921.     mov    ax, es:[di]
  922.     xchg    ah, al
  923.     cmp     ax, 1500
  924.     ja    BlueBookPacket
  925.     inc    di            ;set di to 802.2 header
  926.     inc    di
  927.     mov    dl, IEEE8023
  928. BlueBookPacket:
  929.     call    recv_find               ;request a Rx buffer to store Rx data
  930.  
  931.     mov     ax,es                   ;is this pointer null?
  932.     or      ax,di
  933.     jnz     find_buffer
  934.     jmp     short CheckTx                 ;yes - just free the frame.
  935. find_buffer:
  936.     push    es
  937.     push    di                   ;remember where the buffer pointer is.
  938.     assume  ds:nothing
  939.     mov     bx,RxStartAdd
  940.     mov     cx,RW_ADR
  941.     loadport
  942.     setport DAT
  943.     write_sub_fast    bl
  944.     write_sub_fast    bh
  945.  
  946.     cld
  947.     mov     bp,RxPktLen             ;CX = the byte count of Rx Packet
  948.     setport STAT
  949.     mov     cx,READ
  950.     mov     ah,ch
  951.     xor     ah,08h
  952. read_mem:
  953.     setport    DAT
  954.     mov     al,ch            ;output our read request.
  955.     out     dx,al
  956.     pause
  957.  
  958.     setport    STAT
  959.     in      al,dx            ;input four bits into bl.
  960.     mov     bl,al
  961.     setport    DAT            ;now output the inverse read request.
  962.     mov     al,ah
  963.     out     dx,al
  964.     pause
  965.  
  966.     setport    STAT
  967.     in      al,dx            ;input the high four bits.
  968.     shr     bl,cl
  969.     and     al,0f0h
  970.     or      al,bl            ;combine the two nibbles.
  971.     stosb
  972.     dec     bp
  973.     jnz     read_mem
  974.  
  975. RxCopy_CheckTx:
  976.     pop     si
  977.     pop     ds
  978.     mov     cx,RxPktLen
  979.  
  980.     call    recv_copy               ;tell them that we copied it.
  981.  
  982.     mov     ax,cs                   ;restore our ds.
  983.     mov     ds,ax
  984.     assume  ds:code
  985.  
  986. CheckTx:
  987.     test    NICstatus,T16           ; Is pending a Tx Packet ?
  988.     jz      return                  ; No, then return.
  989.                                     ; Yes, send this packet.
  990. ;set Tx Pointer at beginning of packet
  991.     mov     bx,TxStartAdd
  992.     mov     cx,TX_ADR
  993.     call    Write_sub
  994.     xchg    bh,bl
  995.     call    Write_sub
  996.  
  997. ;Enable interrupt and start Tx
  998.     mov     bl,Mode_RxPg
  999.     mov     cx,COMMAND
  1000.     call    Write_sub
  1001.     or      bl,TXEN
  1002.     call    Write_sub
  1003. return:
  1004.     mov     al,SLT_PRN
  1005. ;*** CMD sub ***
  1006.     loadport
  1007.     setport CMD
  1008.     out     dx,al
  1009. ;*** End CMD sub ***
  1010.  
  1011.     cmp     PS2,0
  1012.     jnz     Rx_another_pkt
  1013.     setport STAT
  1014.     in      al,dx
  1015.     and     al,40h
  1016.     xor     al,IRQinverse
  1017.     jz      Rx_another_pkt
  1018.     call    trigger_int
  1019. Rx_another_pkt:
  1020.     mov     In_ISR,0
  1021.     ret
  1022.  
  1023.  
  1024. recv1:
  1025.     assume  ds:code
  1026.     mov     NICstatus,al            ; save NIC status
  1027.     loadport
  1028.     setport DAT
  1029.     test    al,GOOD                 ; Is Rx generating interrupt ?
  1030.     mov     al,NUL_CMD
  1031.     out     dx,al
  1032.     jnz     Rx_Good_Pkt1             ; Yes, take care of this situation.
  1033.     mov     al,NICstatus
  1034.     test    al,RXBUSY
  1035.     jz      Enable_Rx1
  1036.     jmp     CheckTx                 ; No, go to check Tx.
  1037.  
  1038. Enable_Rx1:
  1039. ;change Rx page & enable NIC to Rx
  1040.     mov     bl,Mode_RxPg
  1041.     mov     cx,COMMAND
  1042.     setport DAT
  1043.     write_sub_slow    bl
  1044.     call    delay
  1045.     or      bl,RXEN
  1046.     write_sub_slow    bl
  1047.     jmp     CheckTx
  1048.  
  1049. Rx_Good_Pkt1:
  1050. ;Put it on the receive queue
  1051.     mov     cx,RX_LEN               ; read Rx Packet Length
  1052.     loadport
  1053.     read_sub_slow    bl
  1054.     read_sub_slow    bh
  1055.  
  1056.     sub     bx,4                    ;subtrate 4 CRC Byte Count
  1057.     mov     RxPktLen,bx             ;save Rx Packet Length
  1058.  
  1059. ;change Rx page & enable NIC to Rx
  1060.     xor     Mode_RxPg,10h
  1061.     mov     bl,Mode_RxPg
  1062.     mov     cx,COMMAND
  1063.     setport DAT
  1064.     write_sub_slow    bl
  1065.     call    delay
  1066.     or      bl,RXEN
  1067.     write_sub_slow    bl
  1068.     call    delay
  1069.     xor     bx,bx
  1070.     mov     bh,CurRxPage            ;BL = Current Rx Page
  1071.     xor     CurRxPage,10h           ;change to next page for Rx
  1072.     shr     bx,1                    ;shift BX to real memory address
  1073.     mov     RxStartAdd,bx           ;save just Rx Packet Start Address
  1074.  
  1075.     add     bx,EADDR_LEN+EADDR_LEN  ;seek to the TYPE word
  1076.     mov     cx,RW_ADR
  1077.     write_sub_slow    bl
  1078.     call    delay
  1079.     write_sub_slow    bh
  1080.     call    delay
  1081.     mov     cx,READ                 ;read the TYPE word
  1082.  
  1083.     read_sub_slow    bl
  1084.     read_sub_slow    bh
  1085.  
  1086.     mov     our_type,bx             ;save the TYPE word
  1087.  
  1088.     mov     ax,ds
  1089.     mov     es,ax
  1090.     mov     di,offset our_type
  1091.     mov     cx,RxPktLen
  1092.  
  1093.     call    recv_find               ;request a Rx buffer to store Rx data
  1094.  
  1095.     mov     ax,es                   ;is this pointer null?
  1096.     or      ax,di
  1097.     jnz     find_buffer1
  1098.     jmp     CheckTx                 ;yes - just free the frame.
  1099. find_buffer1:
  1100.     push    es
  1101.     push    di                   ;remember where the buffer pointer is.
  1102.     assume  ds:nothing
  1103.     mov     bx,RxStartAdd
  1104.     mov     cx,RW_ADR
  1105.     loadport
  1106.     setport DAT
  1107.     write_sub_slow    bl
  1108.     call    delay
  1109.     write_sub_slow    bh
  1110.     call    delay
  1111.  
  1112.     cld
  1113.     mov     bp,RxPktLen             ;CX = the byte count of Rx Packet
  1114.     setport STAT
  1115.     mov     cx,READ
  1116.     mov     ah,ch
  1117.     xor     ah,08h
  1118. read_mem1:
  1119.     dec     dx
  1120.     mov     al,ch
  1121.     out     dx,al
  1122.     call    delay
  1123.  
  1124.     inc     dx
  1125.     in      al,dx
  1126.     mov     bl,al
  1127.     dec     dx
  1128.     mov     al,ah
  1129.     out     dx,al
  1130.     call    delay
  1131.  
  1132.     inc     dx
  1133.     in      al,dx
  1134.     shr     bl,cl
  1135.     and     al,0f0h
  1136.     or      al,bl
  1137.     stosb
  1138.     dec     bp
  1139.     jnz     read_mem1
  1140.     jmp     RxCopy_CheckTx
  1141.  
  1142.  
  1143. recv2:
  1144.     assume  ds:code
  1145.     mov     NICstatus,al            ; save NIC status
  1146.     loadport
  1147.     setport DAT
  1148.     test    al,GOOD                 ; Is Rx generating interrupt ?
  1149.     mov     al,NUL_CMD
  1150.     out     dx,al
  1151.     jnz     Rx_Good_Pkt2             ; Yes, take care of this situation.
  1152.     mov     al,NICstatus
  1153.     test    al,RXBUSY
  1154.     jz      Enable_Rx2
  1155.     jmp     CheckTx                 ; No, go to check Tx.
  1156.  
  1157. Enable_Rx2:
  1158. ;change Rx page & enable NIC to Rx
  1159.     mov     bl,Mode_RxPg
  1160.     mov     cx,COMMAND
  1161.     setport DAT
  1162.     write_sub_delay    bl
  1163.     call    delay
  1164.     or      bl,RXEN
  1165.   if 0
  1166.     write_sub_delay    bl
  1167.   else
  1168.     mov     al,bl
  1169.     shl     al,cl
  1170.     or      al,ch
  1171.     xor     al,08h
  1172.     out     dx,al
  1173.     call    delay
  1174.  
  1175.     xor     al,08h
  1176.     out     dx,al
  1177.     call    delay
  1178.  
  1179.     mov     al,bl
  1180.     and     al,0f0h
  1181.     or      al,ch
  1182.     xor     al,08h
  1183.     out     dx,al
  1184.   endif
  1185.     jmp     CheckTx
  1186.  
  1187. Rx_Good_Pkt2:
  1188. ;Put it on the receive queue
  1189.     mov     cx,RX_LEN               ; read Rx Packet Length
  1190.     loadport
  1191.  
  1192.     read_sub_delay    bl, 1
  1193.     read_sub_delay    bh, 0
  1194.  
  1195.     sub     bx,4                    ;subtrate 4 CRC Byte Count
  1196.     mov     RxPktLen,bx             ;save Rx Packet Length
  1197.  
  1198. ;change Rx page & enable NIC to Rx
  1199.     xor     Mode_RxPg,10h
  1200.     mov     bl,Mode_RxPg
  1201.     mov     cx,COMMAND
  1202.     setport DAT
  1203.     write_sub_delay    bl
  1204.     call    delay
  1205.     or      bl,RXEN
  1206.     write_sub_delay    bl
  1207.     call    delay
  1208.  
  1209.     xor     bx,bx
  1210.     mov     bh,CurRxPage            ;BL = Current Rx Page
  1211.     xor     CurRxPage,10h           ;change to next page for Rx
  1212.     shr     bx,1                    ;shift BX to real memory address
  1213.     mov     RxStartAdd,bx           ;save just Rx Packet Start Address
  1214.  
  1215.     add     bx,EADDR_LEN+EADDR_LEN  ;seek to the TYPE word
  1216.     mov     cx,RW_ADR
  1217.     write_sub_delay    bl
  1218.     call    delay
  1219.     write_sub_delay    bh
  1220.     call    delay
  1221.  
  1222.     mov     cx,READ                 ;read the TYPE word
  1223.  
  1224.     read_sub_delay    bl, 1
  1225.     read_sub_delay    bh, 0
  1226.     mov     our_type,bx             ;save the TYPE word
  1227.  
  1228.     mov     ax,ds
  1229.     mov     es,ax
  1230.     mov     di,offset our_type
  1231.     mov     cx,RxPktLen
  1232.  
  1233.     call    recv_find               ;request a Rx buffer to store Rx data
  1234.  
  1235.     mov     ax,es                   ;is this pointer null?
  1236.     or      ax,di
  1237.     jnz     find_buffer2
  1238.     jmp     CheckTx                 ;yes - just free the frame.
  1239. find_buffer2:
  1240.     push    es
  1241.     push    di                   ;remember where the buffer pointer is.
  1242.     assume  ds:nothing
  1243.     mov     bx,RxStartAdd
  1244.     mov     cx,RW_ADR
  1245.     loadport
  1246.     setport DAT
  1247.     write_sub_delay    bl
  1248.     call    delay
  1249.     write_sub_delay    bh
  1250.     call    delay
  1251.  
  1252.     cld
  1253.     mov     bp,RxPktLen             ;CX = the byte count of Rx Packet
  1254.     setport STAT
  1255.     mov     cx,READ
  1256.     mov     ah,ch
  1257.     xor     ah,08h
  1258. read_mem2:
  1259.     dec     dx
  1260.     mov     al,ch
  1261.     out     dx,al
  1262.     call    delay
  1263.  
  1264.     inc     dx
  1265.     in      al,dx
  1266.     mov     bl,al
  1267.     dec     dx
  1268.     mov     al,ah
  1269.     out     dx,al
  1270.     call    delay
  1271.  
  1272.     inc     dx
  1273.     in      al,dx
  1274.     shr     bl,cl
  1275.     and     al,0f0h
  1276.     or      al,bl
  1277.     stosb
  1278.     dec     bp
  1279.     jnz     read_mem2
  1280.     jmp     RxCopy_CheckTx
  1281.  
  1282.  
  1283.     public    recv_exiting
  1284. recv_exiting:
  1285. ;called from the recv isr after interrupts have been acknowledged.
  1286. ;Only ds and ax have been saved.
  1287.     assume    ds:nothing
  1288.     ret
  1289.  
  1290.  
  1291.     public  end_resident
  1292. end_resident    label   byte
  1293. ;any code after this will not be kept after initialization.
  1294.  
  1295.     public  usage_msg
  1296. usage_msg       db      "usage: DE600PD <packet_int_no>",CR,LF,'$'
  1297.  
  1298.     public  copyright_msg
  1299. copyright_msg   db      "Packet driver for the D-Link DE-600, "
  1300.             db      "version ",'0'+(majver / 10),'0'+(majver mod 10),".",'0'+version,CR,LF,'$'
  1301.             db      "Portions Copyright 1988, Robert C. Clements, K1BC"
  1302.             db      CR,LF,'$'
  1303.  
  1304. CableErr        db      "Bad cable connection.",07,CR,LF,'$'
  1305. mem_error_msg   db      "Adapter memory buffer failure, or bad printer "
  1306.             db      "port connection.",07,CR,LF,'$'
  1307. irq_error_msg   db      "IRQ unavailable, please check other hardware in "
  1308.             db      "computer.",07,CR,LF,'$'
  1309. no_NIC_err      db      "Adapter not found, or AC adapter power is off.",07,CR,LF,'$'
  1310.  
  1311.     extrn   set_recv_isr: near
  1312.  
  1313. ;enter with si -> argument string, di -> word to store.
  1314. ;if there is no number, don't change the number.
  1315.     extrn    get_number: near
  1316.  
  1317. ;enter with dx -> name of word, di -> dword to print.
  1318.     extrn    print_number: near
  1319.  
  1320.     assume  ds:code
  1321.     public  parse_args
  1322. parse_args:
  1323.     ret
  1324.  
  1325.  
  1326.     public  print_parameters
  1327. print_parameters:
  1328.     ret
  1329.  
  1330. cable_err:
  1331.     mov     dx,offset CableErr
  1332.     jmp     short show_msg
  1333. IRQ_error:
  1334.     mov     dx,offset irq_error_msg
  1335.     jmp     short show_msg
  1336. no_our_NIC:
  1337.     mov     dx,offset no_NIC_err
  1338.     jmp     short show_msg
  1339. mem_error:
  1340.     mov     dx,offset mem_error_msg
  1341. show_msg:
  1342.     mov     ah,9
  1343.     int     21h
  1344.     stc
  1345.     ret
  1346.  
  1347.     public  etopen
  1348. etopen:
  1349. ;  Initialize the Ethernet board.
  1350.     call    check_PS2
  1351.  
  1352.     xor     ax,ax
  1353.     mov     es,ax
  1354.     mov     si,PRNTABADD-2          ; point to printer table at low memory
  1355. next_prn_port:
  1356.     add     si,2
  1357.     mov     bx,es:[si]              ; get LPTx's I/O Base
  1358.     or      bx,bx                   ; Does LPTx really exist ?
  1359.     jz      Chk_out_of_range
  1360.     mov     io_addr,bx              ; save the I/O Base number
  1361.     mov     printer,si              ; memorize it's LPTx now
  1362.     call    Check_DE600             ; Yes, BX = I/O Base, then check.
  1363.     jnc     IO_good                 ; If carry flag is clear, so go to
  1364.     mov     al,NML_PRN
  1365.     call    CMD_sub
  1366. Chk_out_of_range:
  1367.     cmp     si,PRNTABADD+6          ; We still miss our card from LPT1 to
  1368.     jb      next_prn_port
  1369.     jmp     short no_our_NIC        ; We still miss our card from LPT1 to
  1370.                                     ; LPT4. We give it up.
  1371. IO_good:
  1372. ; Copy our Ethernet address from PROM into DE600.
  1373.     push    ds
  1374.     pop     es
  1375.     mov     di,offset our_address
  1376.     mov     cx,RW_ADR
  1377.     xor     bl,bl
  1378.     call    Write_sub
  1379.     or      bl,HA13
  1380.     call    Write_sub
  1381.  
  1382.     cld
  1383.     mov     bp,EADDR_LEN
  1384.     mov     cx,READ
  1385. get_our_address:
  1386.     call    Read_sub
  1387.     mov     al,bl
  1388.     stosb
  1389.     dec     bp
  1390.     jnz     get_our_address
  1391.  
  1392.     mov     si,offset our_address    ;make sure it's got the right magic
  1393.     cmp     word ptr es:[si],0de00h    ;  number.
  1394.     jne     no_our_NIC
  1395.     cmp     byte ptr es:[si+2],15h
  1396.     jne     no_our_NIC
  1397.  
  1398.     mov     word ptr es:[si],8000h    ;now modify it to the address assigned
  1399.     mov     byte ptr es:[si+2],0c8h    ;  by Xerox.
  1400.     and     byte ptr es:[si+3],0fh
  1401.     or      byte ptr es:[si+3],070h
  1402.  
  1403.     mov     cx,EADDR_LEN
  1404.     call    set_address
  1405.  
  1406. ; Check DE600's IRQ enviroment
  1407.     call    Check_IRQ
  1408.     cmp     bx,1
  1409.     je      cable_OK
  1410.     jmp     cable_err
  1411.  
  1412. cable_OK:
  1413.     mov     bx,offset delay
  1414.     mov     byte ptr [bx],0c3h     ;  ret
  1415.  
  1416. ; test 8 KBytes memory
  1417. ;********** write mode 1 *************
  1418.     mov     cx,700h
  1419.     mov     al,PAGE3
  1420.     call    Write_LoopBack_Data
  1421.     xor     bx,bx
  1422.     mov     si,bx
  1423. write_next_page:
  1424.     call    Tx_Data
  1425.     push    bx
  1426.     mov     cx,RW_ADR
  1427.     loadport
  1428.     setport DAT
  1429.     write_sub_fast    bl
  1430.     write_sub_fast    bh
  1431.  
  1432.     mov     bx,si
  1433.     mov     bp,800h
  1434.     mov     cx,WRITE
  1435.     mov     ah,ch
  1436.     xor     ah,08h
  1437. wr_this_page:
  1438.     mov     al,bl
  1439.     shl     al,cl
  1440.     or      al,ch
  1441.     out     dx,al
  1442.     mov     al,bl
  1443.     and     al,0f0h
  1444.     or      al,ah
  1445.     out     dx,al
  1446.     inc     bl
  1447.     dec     bp
  1448.     jnz     wr_this_page
  1449.     inc     si
  1450.     pop     bx
  1451.     add     bx,800h
  1452.     cmp     bx,1800h
  1453.     ja      read_memory
  1454.     jmp     short write_next_page
  1455.  
  1456. ;************ read mode 1 ************
  1457. read_memory:
  1458.     loadport
  1459.     setport DAT
  1460.     xor     bx,bx
  1461.     mov     si,bx
  1462. read_next_page:
  1463.     push    bx
  1464.     mov     cx,RW_ADR
  1465.     write_sub_fast    bl
  1466.     write_sub_fast    bh
  1467.  
  1468.     mov     bx,si
  1469.     mov     bp,800h
  1470.     mov     cx,READ
  1471.     mov     ah,ch
  1472.     xor     ah,08h
  1473. rd_this_page:
  1474.     mov     al,ch
  1475.     out     dx,al
  1476.     pause
  1477.     inc     dx
  1478.     in      al,dx
  1479.     mov     bh,al
  1480.     dec     dx
  1481.     mov     al,ah
  1482.     out     dx,al
  1483.     pause
  1484.     inc     dx
  1485.     in      al,dx
  1486.     shr     bh,cl
  1487.     and     al,0f0h
  1488.     or      bh,al
  1489.     cmp     bh,bl
  1490.     jne     memory_test
  1491.     dec     dx
  1492.     inc     bl
  1493.     dec     bp
  1494.     jnz     rd_this_page
  1495.     inc     si
  1496.     pop     bx
  1497.     add     bx,800h
  1498.     cmp     bx,1800h
  1499.     ja      mem_is_OK
  1500.     push    si
  1501.     push    bx
  1502.     mov     cx,700h
  1503.     mov     al,PAGE0
  1504.     call    Write_LoopBack_Data
  1505.     call    Tx_Data
  1506.     pop     bx
  1507.     pop     si
  1508.     jmp     short read_next_page
  1509. mem_is_OK:
  1510.     jmp     mem_OK
  1511.  
  1512. ;************ write mode 2 ***************
  1513. memory_test:
  1514.     pop     ax
  1515. memory_test1:
  1516.     mov     cx,700h
  1517.     mov     al,PAGE3
  1518.     call    Write_LoopBack_Data
  1519.     xor     bx,bx
  1520.     mov     si,bx
  1521. write_next_page1:
  1522.     call    Tx_Data
  1523.     push    bx
  1524.     mov     cx,RW_ADR
  1525.     loadport
  1526.     setport DAT
  1527.     write_sub_slow    bl
  1528.     call    delay
  1529.     write_sub_slow    bh
  1530.     call    delay
  1531.  
  1532.     mov     bx,si
  1533.     mov     bp,800h
  1534.     mov     cx,WRITE
  1535.     mov     ah,ch
  1536.     xor     ah,08h
  1537. wr_this_page1:
  1538.     mov     al,bl
  1539.     shl     al,cl
  1540.     or      al,ch
  1541.     out     dx,al
  1542.     call    delay
  1543.  
  1544.     mov     al,bl
  1545.     and     al,0f0h
  1546.     or      al,ah
  1547.     out     dx,al
  1548.     call    delay
  1549.     inc     bl
  1550.     dec     bp
  1551.     jnz     wr_this_page1
  1552.     inc     si
  1553.     pop     bx
  1554.     add     bx,800h
  1555.     cmp     bx,1800h
  1556.     ja      read_memory1
  1557.     jmp     short write_next_page1
  1558.  
  1559. ;************* read mode 2 **************
  1560. read_memory1:
  1561.     loadport
  1562.     setport DAT
  1563.     xor     bx,bx
  1564.     mov     si,bx
  1565. read_next_page1:
  1566.     push    bx
  1567.     mov     cx,RW_ADR
  1568.     write_sub_slow    bl
  1569.     call    delay
  1570.     write_sub_slow    bh
  1571.     call    delay
  1572.  
  1573.     mov     bx,si
  1574.     mov     bp,800h
  1575.     mov     cx,READ
  1576.     mov     ah,ch
  1577.     xor     ah,08h
  1578. rd_this_page1:
  1579.     mov     al,ch
  1580.     out     dx,al
  1581.     call    delay
  1582.  
  1583.     inc     dx
  1584.     in      al,dx
  1585.     mov     bh,al
  1586.     dec     dx
  1587.     mov     al,ah
  1588.     out     dx,al
  1589.     call    delay
  1590.  
  1591.     inc     dx
  1592.     in      al,dx
  1593.     shr     bh,cl
  1594.     and     al,0f0h
  1595.     or      bh,al
  1596.     cmp     bh,bl
  1597.     jne     memory_test2
  1598.     dec     dx
  1599.     inc     bl
  1600.     dec     bp
  1601.     jnz     rd_this_page1
  1602.     inc     si
  1603.     pop     bx
  1604.     add     bx,800h
  1605.     cmp     bx,1800h
  1606.     ja      mem_is_OK1
  1607.     push    si
  1608.     push    bx
  1609.     mov     cx,700h
  1610.     mov     al,PAGE0
  1611.     call    Write_LoopBack_Data
  1612.     call    Tx_Data
  1613.     pop     bx
  1614.     pop     si
  1615.     jmp     read_next_page1
  1616. mem_is_OK1:
  1617.     jmp     mem_OK1
  1618.  
  1619. ;************* write mode 3 ***************
  1620. memory_test2:
  1621.     pop     ax
  1622. memory_test3:
  1623.     mov     cx,700h
  1624.     mov     al,PAGE3
  1625.     call    Write_LoopBack_Data
  1626.     xor     bx,bx
  1627.     mov     si,bx
  1628. write_next_page3:
  1629.     call    Tx_Data
  1630.     push    bx
  1631.     mov     cx,RW_ADR
  1632.     loadport
  1633.     setport DAT
  1634.     write_sub_delay    bl
  1635.     call    delay
  1636.     write_sub_delay    bh
  1637.     call    delay
  1638.  
  1639.     mov     bx,si
  1640.     mov     bp,800h
  1641.     mov     cx,WRITE
  1642. wr_this_page3:
  1643.     mov     al,bl
  1644.     shl     al,cl
  1645.     or      al,ch
  1646.     xor     al,08h
  1647.     out     dx,al
  1648.     call    delay
  1649.  
  1650.     xor     al,08h
  1651.     out     dx,al
  1652.     call    delay
  1653.  
  1654.     mov     al,bl
  1655.     and     al,0f0h
  1656.     or      al,ch
  1657.     out     dx,al
  1658.     call    delay
  1659.  
  1660.     xor     al,08h
  1661.     out     dx,al
  1662.     call    delay
  1663.     inc     bl
  1664.     dec     bp
  1665.     jnz     wr_this_page3
  1666.     inc     si
  1667.     pop     bx
  1668.     add     bx,800h
  1669.     cmp     bx,1800h
  1670.     ja      read_memory3
  1671.     jmp     write_next_page3
  1672.  
  1673. ;************* read mode 3 ***************
  1674. read_memory3:
  1675.     loadport
  1676.     setport DAT
  1677.     xor     bx,bx
  1678.     mov     si,bx
  1679. read_next_page3:
  1680.     push    bx
  1681.     mov     cx,RW_ADR
  1682.     write_sub_delay    bl
  1683.     call    delay
  1684.     write_sub_delay    bh
  1685.  
  1686.     call    delay
  1687.  
  1688.     mov     bx,si
  1689.     mov     bp,800h
  1690.     mov     cx,READ
  1691.     mov     ah,ch
  1692.     xor     ah,08h
  1693.  
  1694.     mov     al,ch
  1695.     xor     al,08h
  1696.     out     dx,al
  1697.     call    delay
  1698. rd_this_page3:
  1699.     mov     al,ch
  1700.     out     dx,al
  1701.     call    delay
  1702.  
  1703.     setport STAT
  1704.     in      al,dx
  1705.     mov     bh,al
  1706.     setport DAT
  1707.     mov     al,ah
  1708.     out     dx,al
  1709.     call    delay
  1710.  
  1711.     setport STAT
  1712.     in      al,dx
  1713.     shr     bh,cl
  1714.     and     al,0f0h
  1715.     or      bh,al
  1716.     cmp     bh,bl
  1717.     jne     mem_err
  1718.     setport    DAT
  1719.     inc     bl
  1720.     dec     bp
  1721.     jnz     rd_this_page3
  1722.     inc     si
  1723.     pop     bx
  1724.     add     bx,800h
  1725.     cmp     bx,1800h
  1726.     ja      mem_OK2
  1727.     push    si
  1728.     push    bx
  1729.     mov     cx,700h
  1730.     mov     al,PAGE0
  1731.     call    Write_LoopBack_Data
  1732.     call    Tx_Data
  1733.     pop     bx
  1734.     pop     si
  1735.     jmp     read_next_page3
  1736.  
  1737. pointer         dw      0
  1738.  
  1739. mem_err:
  1740.     pop     bx
  1741.     cmp     pointer,9        ;too slow?  Must not be working.
  1742.     ja      mem_real_err
  1743.     mov     bx,offset delay        ;append another NOP and RET in.
  1744.     add     bx,pointer
  1745.     mov     [bx],0c390h
  1746.     inc     pointer            ;slow it down a little more and try
  1747.     jmp     memory_test3        ;  again.
  1748. mem_real_err:
  1749.     jmp     mem_error
  1750.  
  1751. change_routine:
  1752.     mov     ax,offset recv1
  1753.     mov     recv_pointer,ax
  1754.     mov     ax,offset send_pkt1
  1755.     mov     send_pkt_pointer,ax
  1756.     ret
  1757.  
  1758. change_routine2:
  1759.     mov     ax,offset recv2
  1760.     mov     recv_pointer,ax
  1761.     mov     ax,offset send_pkt2
  1762.     mov     send_pkt_pointer,ax
  1763.     ret
  1764.  
  1765. ;********** memory test passed ****************
  1766. mem_OK1:
  1767.     call    change_routine
  1768.     jmp     short mem_OK
  1769. mem_OK2:
  1770.     call    change_routine2
  1771. mem_OK:
  1772.     call    speed_test
  1773.  
  1774.     push    es
  1775.     xor     ax,ax
  1776.     mov     es,ax
  1777.     mov     si,printer
  1778.     mov     word ptr es:[si],ax     ; Zero-out Printer Port
  1779.     pop     es
  1780.  
  1781. ; Initialize Rx buffer pointer, and start receive
  1782.     mov     bl,Mode
  1783.     or      bl,IRQinverse
  1784.     or      bl,CurRXPage
  1785.     mov     Mode_RxPg,bl
  1786.     mov     cx,COMMAND
  1787.     call    Write_sub
  1788.     or      bl,RXEN
  1789.     call    Write_sub
  1790.  
  1791. ; Put our Receive routine in interrupt chain
  1792.     call    set_recv_isr
  1793.  
  1794. ; We didn't need to enable the receive & transmit interrupts, they were
  1795. ; set by hardware already. (accept GOOD, SUC & T16 to generate interrupt)
  1796.  
  1797. ; Enable Printer Adapter IRQ line
  1798.     mov     al,SLT_PRN
  1799.     call    CMD_sub
  1800.  
  1801.     mov     dx,offset end_resident
  1802.     clc
  1803.     ret
  1804.  
  1805.  
  1806. ;*********** sub-routine *************
  1807. ; Check DE-600 routine
  1808. Check_DE600:
  1809.     mov     al,SLT_NIC
  1810.     call    CMD_sub
  1811.     call    delay
  1812.  
  1813.     loadport
  1814.     setport DAT
  1815.     mov     al,NUL_CMD
  1816.     out     dx,al
  1817.     call    delay
  1818.  
  1819.     mov     bl,RESET
  1820.     mov     cx,COMMAND
  1821.     call    Write_sub
  1822.     call    delay
  1823.     mov     bl,STOP_RESET
  1824.     call    Write_sub
  1825.     call    delay
  1826.  
  1827.     mov     cx,STATUS
  1828.     call    Read_sub
  1829.     test    bl,0f0h
  1830.     jz      Check_OK
  1831.     stc
  1832.     ret
  1833. Check_OK:
  1834.     clc
  1835.     ret
  1836.  
  1837. OldIRQ5 dd      0
  1838. OldIRQ7 dd      0
  1839.  
  1840. NewIRQ5:
  1841.     push    ax
  1842.     push    bx
  1843.     push    cx
  1844.     push    dx
  1845.     push    ds
  1846.     mov     al,20h
  1847.     out     20h,al
  1848.     mov     ax,cs
  1849.     mov     ds,ax
  1850.     cmp     LB,0
  1851.     jz      DisCare_IRQ5
  1852.     mov     bh,5
  1853.     call    Clear_int
  1854. DisCare_IRQ5:
  1855.     pop     ds
  1856.     pop     dx
  1857.     pop     cx
  1858.     pop     bx
  1859.     pop     ax
  1860.     iret
  1861.  
  1862. NewIRQ7:
  1863.     push    ax
  1864.     push    bx
  1865.     push    cx
  1866.     push    dx
  1867.     push    ds
  1868.     mov     al,20h
  1869.     out     20h,al
  1870.     mov     ax,cs
  1871.     mov     ds,ax
  1872.     cmp     LB,0
  1873.     jz      DisCare_IRQ7
  1874.     mov     bh,7
  1875.     call    Clear_int
  1876. DisCare_IRQ7:
  1877.     pop     ds
  1878.     pop     dx
  1879.     pop     cx
  1880.     pop     bx
  1881.     pop     ax
  1882.     iret
  1883.  
  1884. replace_IRQ5_7:
  1885.     xor     cx,cx
  1886.     mov     es,cx
  1887.     mov     di,034h
  1888.     mov     ax,es:[di]                      ;save old interrupt vector
  1889.     mov     word ptr OldIRQ5,ax
  1890.     mov     ax,es:[di]+2
  1891.     mov     word ptr OldIRQ5+2,ax
  1892.     mov     ax,offset NewIRQ5
  1893.     stosw
  1894.     mov     ax,cs
  1895.     stosw
  1896.  
  1897.     mov     di,03ch
  1898.     mov     ax,es:[di]                      ;save old interrupt vector
  1899.     mov     word ptr OldIRQ7,ax
  1900.     mov     ax,es:[di]+2
  1901.     mov     word ptr OldIRQ7+2,ax
  1902.     mov     ax,offset NewIRQ7
  1903.     stosw
  1904.     mov     ax,cs
  1905.     stosw
  1906.  
  1907.     in      al,21h
  1908.     mov     intmask,al
  1909.     pause
  1910.     pause
  1911.     and     al,5fh
  1912.     out     21h,al
  1913.     ret
  1914.  
  1915. intmask         db      0
  1916. INT_come        db      0
  1917. T16_flag        db      0
  1918. LB              db      0
  1919.  
  1920. restore_IRQ5_7:
  1921.     xor     cx,cx
  1922.     mov     es,cx
  1923.     mov     di,034h
  1924.     mov     ax,word ptr OldIRQ5
  1925.     mov     es:[di],ax                      ;save old interrupt vector
  1926.     mov     ax,word ptr OldIRQ5+2
  1927.     mov     es:[di]+2,ax
  1928.  
  1929.     mov     di,03ch
  1930.     mov     ax,word ptr OldIRQ7
  1931.     mov     es:[di],ax                      ;save old interrupt vector
  1932.     mov     ax,word ptr OldIRQ7+2
  1933.     mov     es:[di]+2,ax
  1934.  
  1935.     mov     al,intmask
  1936.     out     21h,al
  1937.     ret
  1938.  
  1939. Write_LoopBack_Data:
  1940.     mov     si,offset our_address
  1941.     mov     di,si
  1942. ;set Tx Pointer for moving packet
  1943.     mov     bx,BFRSIZ
  1944.     sub     bx,cx           ;CX= Packet Length
  1945.     or      bh,al           ;AL= Page Number
  1946.     mov     TxStartAdd,bx   ;BX= the pointer to TX
  1947.     mov     cx,RW_ADR       ;write memory address
  1948.     call    Write_sub
  1949.     mov     bl,bh
  1950.     call    Write_sub
  1951.     cld
  1952.     loadport
  1953.     setport DAT
  1954.     mov     bp,12
  1955.     mov     cx,WRITE
  1956. write_our_node_ID:
  1957.     lodsb
  1958.     mov     bl,al
  1959.     call    Write_sub
  1960.     cmp     bp,7
  1961.     jne     not_second_ID
  1962.     mov     si,di
  1963. not_second_ID:
  1964.     dec     bp
  1965.     jnz     write_our_node_ID
  1966.     ret
  1967.  
  1968. Tx_Data:
  1969. ;Check TXIDLE, if high then wait for previous Tx end, if low then Tx it
  1970.     mov     cx,800h        ; Avoid infinite loop
  1971.     loadport
  1972.     setport STAT
  1973. wait_Txidle0:
  1974.     in      al,dx
  1975.     test    al,TXBUSY       ; Is the previous Tx successful ?
  1976.     jz      Tx_next0        ; Yes, TXBUSY is low. Then could Tx next packet.
  1977.     loop    wait_Txidle0
  1978. Tx_next0:
  1979. ;set Tx Pointer at beginning of packet
  1980.     push    bx
  1981.     mov     cx,TX_ADR
  1982.     mov     bx,TxStartAdd
  1983.     call    Write_sub
  1984.     mov     bl,bh
  1985.     call    Write_sub
  1986. ;Enable interrupt and start Tx
  1987.     mov     cx,COMMAND
  1988.     mov     bl,RX_NONE
  1989.     call    Write_sub
  1990.     or      bl,TXEN
  1991.     call    Write_sub
  1992.     pop     bx
  1993.     ret
  1994.  
  1995. LoopBack_Tx:
  1996. ;set Tx Pointer at beginning of packet
  1997.     mov     bx,TxStartAdd
  1998.     mov     cx,TX_ADR
  1999.     call    Write_sub
  2000.     mov     bl,bh
  2001.     call    Write_sub
  2002. ;Enable interrupt and start Tx
  2003.     mov     bl,RX_BP
  2004.     or      bl,IRQinverse
  2005.     mov     cx,COMMAND
  2006.     call    Write_sub
  2007.     or      bl,LOOPBACK
  2008.     call    Write_sub
  2009.  
  2010.     mov     LB,1
  2011.     mov     al,SLT_PRN
  2012.     call    CMD_sub
  2013.  
  2014.     xor     bx,bx
  2015.     mov     cx,8000h
  2016. wait_int:
  2017.     cmp     INT_come,0
  2018.     jz      have_T16
  2019.     mov     bx,1
  2020.     jmp     short exit_LoopBack
  2021. have_T16:
  2022.     cmp     T16_flag,0
  2023.     jz      still_wait
  2024.     mov     bx,-1
  2025.     jmp     short exit_LoopBack
  2026. still_wait:
  2027.     loop    wait_int
  2028.  
  2029. exit_LoopBack:
  2030.     mov     LB,0
  2031.     mov     al,SLT_NIC
  2032.     call    CMD_sub
  2033.  
  2034.     push    bx
  2035.     mov     cx,STATUS
  2036.     call    Read_sub
  2037.     pop     bx
  2038.     ret
  2039.  
  2040. Clear_int:
  2041.     mov     al,SLT_NIC
  2042.     call    CMD_sub
  2043.     pause
  2044.     mov     cx,STATUS
  2045.     call    Read_sub
  2046.  
  2047.     mov     T16_flag,0
  2048.     test    bl,GOOD         ; Is Rx generating interrupt ?
  2049.     jz      chk_T16
  2050.     mov     INT_come,1
  2051.     mov     int_no,bh
  2052.     jmp     short exit_Clear_int
  2053. chk_T16:
  2054.     test    bl,T16          ; Is pending a Tx Packet ?
  2055.     jz      exit_Clear_int
  2056.     mov     T16_flag,1
  2057. exit_Clear_int:
  2058.     ret
  2059.  
  2060. Check_IRQ:
  2061.     call    replace_IRQ5_7
  2062.     sti
  2063.     mov     cx,RUNT
  2064.     mov     al,PAGE0
  2065.     call    Write_LoopBack_Data
  2066.     call    LoopBack_Tx     ; check IRQ= 7 or 5 but IRQ not inverse
  2067.     cmp     bx,0
  2068.     jnz     IRQ_OK
  2069.  
  2070. ;Check TXIDLE, if high then wait for previous Tx end, if low then Tx it
  2071.     mov     cx,800h        ; Avoid infinite loop
  2072.     loadport
  2073.     setport STAT
  2074. wait_Txidle:
  2075.     in      al,dx
  2076.     test    al,TXBUSY       ; Is the previous Tx successful ?
  2077.     jz      Tx_next         ; Yes, TXBUSY is low. Then could Tx next packet.
  2078.     loop    wait_Txidle
  2079. Tx_next:
  2080.     mov     IRQinverse,40h  ; check IRQ= 7 or 5 but IRQ inverse
  2081.     mov     PS2,0
  2082.     call    LoopBack_Tx
  2083. IRQ_OK:
  2084.     cli
  2085.     call    restore_IRQ5_7
  2086.     ret
  2087.  
  2088. check_PS2:
  2089.     mov     ax,0c400h
  2090.     int     15h
  2091.     jc      not_PS2
  2092.     mov     PS2,1
  2093. not_PS2:
  2094.     ret
  2095.  
  2096. speed_test:
  2097.     xor     ax,ax
  2098.     mov     es,ax
  2099.     mov     si,20h
  2100.     mov     ax, es:[si]
  2101.     mov     cs:old_int8, ax
  2102.     mov     ax, es:[si+2]
  2103.     mov     cs:old_int8[2], ax
  2104.     cli
  2105.     mov     ax,offset new_int8
  2106.     mov     es:[si],ax
  2107.     mov     es:[si+2],cs
  2108.     sti
  2109.  
  2110. next_test1:
  2111.     mov     ticks_start,0
  2112. next_test:
  2113.     cmp     ticks_start,0
  2114.     jz      next_test
  2115.     mov     ticks,0
  2116.     xor     bx,bx
  2117. loop_again:
  2118.     mov     cx,6
  2119.     loop    $
  2120.     cmp     ticks,2
  2121.     jae     End_count
  2122.     inc     bx
  2123.     jmp     short loop_again
  2124.  
  2125. End_count:
  2126.     cli
  2127.     xor     ax,ax
  2128.     mov     es,ax
  2129.     mov     si,20h
  2130.     mov     ax,old_int8
  2131.     mov     es:[si],ax
  2132.     mov     ax,old_int8[2]
  2133.     mov     es:[si+2],ax
  2134.     sti
  2135.     cmp     bx,0a000h
  2136.     jb      low_speed
  2137.     mov     ax,offset recv1         ; special for high speed EISA
  2138.     mov     recv_pointer,ax
  2139. low_speed:
  2140.     ret
  2141.  
  2142. ticks_start     db      0
  2143. ticks           db      0
  2144. old_int8        dw      ?
  2145.             dw      ?
  2146. new_int8:
  2147.     inc     ticks
  2148.     inc     ticks_start
  2149.     jmp     dword ptr cs:old_int8
  2150.  
  2151.     code    ends
  2152.     end
  2153.